package com.thread.threadfirst.javaBase.classLoader;

/**
 * 类加载器分类：
 *
 * 系统级别：
 * 	1. 启动类加载器 BootstrapClassLoader：C来实现的
 * 	2. 扩展类加载器 ExtClassLoader ：Java实现的，父类都是ClassLoader
 * 	3. 应用类加载器 AppClassLoader ：Java实现的，父类都是ClassLoader
 *
 * 用户级别：
 * 自定义类加载器（继承我们的ClassLoader）
 */
public class ClassLoaderTest {
    public static void main(String[] args) {
//        bootClassLoader();//启动类加载器
//        extClassLoader();//扩展类加载器
//        appClassLoader();//应用类加载器

//        System.out.println(ClassLoaderTest.class.getClassLoader());//此类的类加载器
//        System.out.println(ClassLoaderTest.class.getClassLoader().getParent());//此类的类加载器的父类
//        System.out.println(ClassLoaderTest.class.getClassLoader().getParent().getParent());//此类的类加载器的爷类
        /*
        输出：
        sun.misc.Launcher$AppClassLoader@18b4aac2 //应用类加载器
        sun.misc.Launcher$ExtClassLoader@4e50df2e //扩展类加载器
        null  显示"null"说明此是顶层加载器了 即启动类加载器
        */

        Role role=new Role();//查看类加载过程，调用了ClassLoader的loadClass()
        System.out.println("类加载完成……");
    }

    /**
     * 启动类加载器
     */
    public static void bootClassLoader(){
        String bootClassLoaderPath=System.getProperty("sun.boot.class.path");//启动类加载器负责加载的路径
        String[] bootClassLoaderPathList=bootClassLoaderPath.split(";");
        for (String path : bootClassLoaderPathList) {
            System.out.println("启动类加载器加载路径: "+path);
        }
        /*
        输出：
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\resources.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\rt.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\sunrsasign.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\jsse.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\jce.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\charsets.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\jfr.jar
        启动类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\classes  如果将某个.class文件放到此目录（需要程序员自己创建文件夹）下 也是可以被启动类加载器加载到JVM中的。
        */
    }

    /**
     * 扩展类加载器
     */
    public static void extClassLoader(){
        String bootClassLoaderPath=System.getProperty("java8.ext.dirs");//扩展类加载器负责加载的路径
        String[] bootClassLoaderPathList=bootClassLoaderPath.split(";");
        for (String path : bootClassLoaderPathList) {
            System.out.println("扩展类加载器加载路径: "+path);
        }
        /*
        输出：
        扩展类加载器加载路径: C:\Program Files\Java\jdk1.8.0_77\jre\lib\ext
        扩展类加载器加载路径: C:\Windows\Sun\Java\lib\ext
        */
    }

    /**
     * 应用类加载器
     */
    public static void appClassLoader(){
        String bootClassLoaderPath=System.getProperty("java8.class.path");//应用类加载器负责加载的路径
        String[] bootClassLoaderPathList=bootClassLoaderPath.split(";");
        for (String path : bootClassLoaderPathList) {
            System.out.println("应用类加载器加载路径: "+path);
        }
        /*
        输出：
        应用类加载器加载路径: D:\exercise\target\classes
        应用类加载器加载路径: C:\Users\fyess\.m2\repository\org\springframework\boot\spring-boot-starter\2.2.2.RELEASE\spring-boot-starter-2.2.2.RELEASE.jar
        应用类加载器加载路径: C:\Users\fyess\.m2\repository\org\springframework\boot\spring-boot\2.2.2.RELEASE\spring-boot-2.2.2.RELEASE.jar
        上面只是一小部分的输出，从输出的路径可看出 还可以加载jar包。
        */
    }
}
